/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package preka.tests;

import prefuse.Constants;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.RepaintAction;
import prefuse.action.assignment.ColorAction;
import prefuse.action.assignment.DataColorAction;
import prefuse.action.layout.graph.ForceDirectedLayout;
import prefuse.activity.Activity;
import prefuse.controls.DragControl;
import prefuse.controls.PanControl;
import prefuse.controls.ZoomControl;
import prefuse.data.Graph;
import prefuse.data.Node;
import prefuse.data.io.GraphMLReader;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.LabelRenderer;
import prefuse.data.io.DataIOException;
import prefuse.util.ColorLib;
import prefuse.visual.VisualItem;

/**
 *
 * @author vhbarros
 */
public class TesteIVC {

    private Visualization m_vis;
    private Graph m_graph;
    private Display m_display;


    public TesteIVC() {

    }

    public void initialize() {

        // *************** 1. Leitura do grafo inicial
        m_graph = new Graph();
        m_graph.addColumn(VisualItem.LABEL, String.class);
        Node n1 = m_graph.addNode();
        n1.set(VisualItem.LABEL, "Node "+n1.getRow());
        Node n2 = m_graph.addNode();
        n2.set(VisualItem.LABEL, "Node "+n2.getRow());
        m_graph.addEdge(n1, n2);



        /*try {
            // TODO Implementar ArffReader - ver base GraphML
            graph = new GraphMLReader().readGraph("/socialnet.xml");
        } catch ( DataIOException e ) {
            e.printStackTrace();
            System.err.println("Error loading graph. Exiting...");
            System.exit(1);
        }*/



        // *************** 2. Criação da visualização
        m_vis = new Visualization();
        m_vis.add("graph", m_graph);                        // O grafo será identificado como "graph" na visualização
                                                          // Os nós e as ligações ficam automaticamente registados como
                                                          // "graph.nodes" e "graph.edges" respectivamente
        m_vis.setInteractive("graph.edges", null, false); // A interactividade com as ligações fica inibida



        // *************** 3. Criação dos renderizadores para definir o aspecto dos nós e das ligações

        // 3.1. O LabelRenderer serve para inserir texto dentro do símbolo visual
        LabelRenderer tr = new LabelRenderer(VisualItem.LABEL);   // TODO mudar nome para class
        tr.setRoundedCorner(8, 8);

        // 3.2. O DefaultRendererFactory é criado com o renderizador por omissão para as ligações
        //      (linhas normais) e o LabelRenderer para os nós
        m_vis.setRendererFactory(new DefaultRendererFactory(tr));



        // *************** 4. Complementar os símbolos visuais com as propriedades visual, neste passo cor!

        // Vector de cores distintas a aplicar às instâncias, correspondende ao número de classes
        // 0 representa transparência e 255 opacidade total
        // TODO Método de criação dinâmica de cores distintas por nº de classes
        int[] palette = new int[] {
            ColorLib.rgb(255,180,180), ColorLib.rgb(190,190,255)
        };

        // 4.1. Definição da cor de fundo de cada objecto (distinta consante a classe real a que pertence)
        //DataColorAction fill = new DataColorAction("graph.nodes",           // Aplica-se aos nós do grafo
        //                                           "gender",                // Campo identificador da classe
        //                                           Constants.NOMINAL,       // Indica que é um identificador de conjunto
        //                                           VisualItem.FILLCOLOR,    // Aplica-se à cor de fundo do nó
        //                                           palette);                // Cores distintas a aplicar aos objectos de cada classe

        // 4.2. Definição da cor do texto
        ColorAction text = new ColorAction("graph.nodes",           // Aplica-se aos nós do grafo
                                           VisualItem.TEXTCOLOR,    // Aplica-se ao texto do objecto
                                           ColorLib.gray(0));       // Preto

        // 4.3. Definição da cor das ligações
        ColorAction edges = new ColorAction("graph.edges",          // Aplica-se às ligações
                                            VisualItem.STROKECOLOR, // Aplica-se à cor das linhas
                                            ColorLib.gray(200));    // Cinza claro


        // 4.4. Criação de uma lista de acções para ser executada (e aplicar as cores) no loop da visualização
        ActionList color = new ActionList();
        //color.add(fill);
        color.add(text);
        color.add(edges);



        // *************** 5. Aplicar um desenho à visualização
        ActionList layout = new ActionList(Activity.INFINITY);  // A acção será executada até ser mandada parar
        layout.add(new ForceDirectedLayout("graph"));           // Aplicação do desenho de forças direccionadas spring embedded ao grafo
        layout.add(new RepaintAction());                        // Para redesenhar a cada ciclo


        // *************** 6. Associar acções à visualização
        m_vis.putAction("color", color);
        m_vis.putAction("layout", layout);



        // *************** 7. Construção da área de apresentação da visualização
        m_display = new Display(m_vis);           // Associa a visualização à area de apresentação
        m_display.setSize(600, 600);                      // Tamanho da área de visualização
        m_display.pan(300, 300);
        m_display.addControlListener(new DragControl());  // Controlo para permitir arrastar as instâncias
        m_display.addControlListener(new PanControl());   // Controlo para mover a visualização com o botão esquerdo do rato
        m_display.addControlListener(new ZoomControl());  // Controlo para fazer zoom o botão direito do rato

    }

    public void run() {
        m_vis.run("color");  // assign the colors
        m_vis.run("layout"); // start up the animated layout
    }

    public Visualization getVisualization() {
        return m_vis;
    }

    public Display getDisplay() {
        return m_display;
    }

    public Graph getGraph() {
        return m_graph;
    }

}
